using System.Linq.Expressions;
using SqlSugar;

namespace ClassDemo.Repository;

/// <summary>
/// 通用Repository基类实现
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
public class BaseRepository<T> : IBaseRepository<T> where T : class, new()
{
    protected readonly SqlSugarClient _db;

    public BaseRepository(SqlSugarClient db)
    {
        _db = db;
    }

    /// <summary>
    /// 根据ID获取实体
    /// </summary>
    /// <param name="id">主键ID</param>
    /// <returns>实体对象</returns>
    public virtual async Task<T?> GetByIdAsync(object id)
    {
        return await _db.Queryable<T>().InSingleAsync(id);
    }

    /// <summary>
    /// 获取所有实体
    /// </summary>
    /// <returns>实体列表</returns>
    public virtual async Task<List<T>> GetAllAsync()
    {
        return await _db.Queryable<T>().ToListAsync();
    }

    /// <summary>
    /// 根据条件查询实体列表
    /// </summary>
    /// <param name="expression">查询条件</param>
    /// <returns>实体列表</returns>
    public virtual async Task<List<T>> GetListAsync(Expression<Func<T, bool>> expression)
    {
        return await _db.Queryable<T>().Where(expression).ToListAsync();
    }

    /// <summary>
    /// 根据条件查询单个实体
    /// </summary>
    /// <param name="expression">查询条件</param>
    /// <returns>实体对象</returns>
    public virtual async Task<T?> GetFirstAsync(Expression<Func<T, bool>> expression)
    {
        return await _db.Queryable<T>().Where(expression).FirstAsync();
    }

    /// <summary>
    /// 分页查询
    /// </summary>
    /// <param name="pageIndex">页码</param>
    /// <param name="pageSize">页大小</param>
    /// <param name="expression">查询条件</param>
    /// <returns>分页结果</returns>
    public virtual async Task<(List<T> Data, int Total)> GetPageListAsync(int pageIndex, int pageSize, Expression<Func<T, bool>>? expression = null)
    {
        RefAsync<int> total = 0;
        var query = _db.Queryable<T>();
        
        if (expression != null)
        {
            query = query.Where(expression);
        }
        
        var data = await query.ToPageListAsync(pageIndex, pageSize, total);
        return (data, total.Value);
    }

    /// <summary>
    /// 添加实体
    /// </summary>
    /// <param name="entity">实体对象</param>
    /// <returns>是否成功</returns>
    public virtual async Task<bool> AddAsync(T entity)
    {
        return await _db.Insertable(entity).ExecuteCommandAsync() > 0;
    }

    /// <summary>
    /// 批量添加实体
    /// </summary>
    /// <param name="entities">实体列表</param>
    /// <returns>是否成功</returns>
    public virtual async Task<bool> AddRangeAsync(List<T> entities)
    {
        return await _db.Insertable(entities).ExecuteCommandAsync() > 0;
    }

    /// <summary>
    /// 更新实体
    /// </summary>
    /// <param name="entity">实体对象</param>
    /// <returns>是否成功</returns>
    public virtual async Task<bool> UpdateAsync(T entity)
    {
        return await _db.Updateable(entity).ExecuteCommandAsync() > 0;
    }

    /// <summary>
    /// 批量更新实体
    /// </summary>
    /// <param name="entities">实体列表</param>
    /// <returns>是否成功</returns>
    public virtual async Task<bool> UpdateRangeAsync(List<T> entities)
    {
        return await _db.Updateable(entities).ExecuteCommandAsync() > 0;
    }

    /// <summary>
    /// 根据条件更新实体
    /// </summary>
    /// <param name="expression">更新条件</param>
    /// <param name="updateExpression">更新表达式</param>
    /// <returns>影响行数</returns>
    public virtual async Task<int> UpdateAsync(Expression<Func<T, bool>> expression, Expression<Func<T, T>> updateExpression)
    {
        return await _db.Updateable<T>().SetColumns(updateExpression).Where(expression).ExecuteCommandAsync();
    }

    /// <summary>
    /// 删除实体
    /// </summary>
    /// <param name="entity">实体对象</param>
    /// <returns>是否成功</returns>
    public virtual async Task<bool> DeleteAsync(T entity)
    {
        return await _db.Deleteable(entity).ExecuteCommandAsync() > 0;
    }

    /// <summary>
    /// 根据ID删除实体
    /// </summary>
    /// <param name="id">主键ID</param>
    /// <returns>是否成功</returns>
    public virtual async Task<bool> DeleteByIdAsync(object id)
    {
        return await _db.Deleteable<T>().In(id).ExecuteCommandAsync() > 0;
    }

    /// <summary>
    /// 根据条件删除实体
    /// </summary>
    /// <param name="expression">删除条件</param>
    /// <returns>影响行数</returns>
    public virtual async Task<int> DeleteAsync(Expression<Func<T, bool>> expression)
    {
        return await _db.Deleteable<T>().Where(expression).ExecuteCommandAsync();
    }

    /// <summary>
    /// 检查实体是否存在
    /// </summary>
    /// <param name="expression">查询条件</param>
    /// <returns>是否存在</returns>
    public virtual async Task<bool> ExistsAsync(Expression<Func<T, bool>> expression)
    {
        return await _db.Queryable<T>().Where(expression).AnyAsync();
    }

    /// <summary>
    /// 获取实体数量
    /// </summary>
    /// <param name="expression">查询条件</param>
    /// <returns>数量</returns>
    public virtual async Task<int> CountAsync(Expression<Func<T, bool>>? expression = null)
    {
        var query = _db.Queryable<T>();
        if (expression != null)
        {
            query = query.Where(expression);
        }
        return await query.CountAsync();
    }
}